package org.tgcloud.group.core;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.apache.commons.lang.RandomStringUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by Administrator on 2016/3/28 0028.
 */
public class StringUtil {

    private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static boolean testEmail(String email) {
        String regex = "\\w+(\\.\\w)*@\\w+(\\.\\w{2,3}){1,3}";
        return email.matches(regex);
    }

    public static final String EMPTY = "";

    private StringUtil() {
    }

    public static final String EMPTY_STRING = "";

    private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};


    public final static String[] charList = {"A", "B", "C", "D", "E", "F", "G", "H", "I",
            "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
            "U", "V", "W", "X", "Y", "Z"};

    private static Random random = new Random();

    //随机字符数组
    public static String[] upperArray = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");

    //随机字符数组
    private static char[] charSequence = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();

    /*随机数字*/
    private static int[] intSequence = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9};

    // 一天的毫秒数
    private static final long DAY_MS = 1 * 24 * 60 * 60 * 1000;
    // 一小时的毫秒数
    private static final long HOURS_MS = 1 * 60 * 60 * 1000;
    // 一分钟的毫秒数
    private static final long MINUTES_MS = 1 * 60 * 1000;
    // 一秒的毫秒数
    private static final long SECONDS_MS = 1 * 1000;

    public static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n = 256 + n;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }

    /**
     * 转换字节数组为16进制字串
     *
     * @param b 字节数组
     * @return 16进制字串
     */
    public static String byteArrayToHexString(byte[] b) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++) {
            resultSb.append(byteToHexString(b[i]));
        }
        return resultSb.toString();
    }

    /**
     * 验证手机号格式是否正确
     *
     * @param phone
     * @return
     */
    public static boolean phoneIsIllegal(String phone) {
        Pattern p = Pattern.compile("^\\d{11}$");
        if (null != phone) {
            phone = phone.trim();
        } else {
            return true;
        }
        Matcher m = p.matcher(phone);
        return !m.matches();
    }

    public static String MD5Encode(String origin) {
        String resultString = null;
        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            resultString = byteArrayToHexString(md.digest(resultString
                    .getBytes("UTF-8")));
        } catch (Exception ex) {
        }
        return resultString;
    }

    public static String generateOrderIdByName(String name) {
        /*订单号生成，保证唯一就行*/
        StringBuilder sRand = new StringBuilder(30);
        sRand.append(name);
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String str = sdf.format(date);
        sRand.append(str);
        for (int i = 0; i < 10; i++) {
            // 取得一个随机数字
            String tmp = StringUtil.getRandomInt() + "";
            sRand.append(tmp);
        }
        return sRand.toString();
    }

    public static String generateOrderId() {
        /*订单号生成，保证唯一就行*/
        StringBuilder sRand = new StringBuilder(30);
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String str = sdf.format(date);
        sRand.append(str);
        for (int i = 0; i < 10; i++) {
            // 取得一个随机数字
            String tmp = StringUtil.getRandomInt() + "";
            sRand.append(tmp);
        }
        return sRand.toString();
    }

    public static String groupAuthCode() {
        /*订单号生成，保证唯一就行*/
        StringBuilder sRand = new StringBuilder(10);
        for (int i = 0; i < 10; i++) {
            // 取得一个随机数字
            String tmp = StringUtil.getRandomChar() + "";
            sRand.append(tmp);
        }
        return sRand.toString();
    }

    /**
     * 获取随机字符
     *
     * @return
     */
    public static String getRandomChar() {
        int index = random.nextInt(charSequence.length);
        return String.valueOf(charSequence[index]);
    }

    /**
     * 获取随机数字
     *
     * @return
     */
    public static int getRandomInt() {
        int index = random.nextInt(intSequence.length);
        return intSequence[index];
    }


    /**
     * 判断一个字符串是否为空，null也会返回true
     *
     * @param str 需要判断的字符串
     * @return 是否为空，null也会返回true
     */
    public static boolean isBlank(String str) {
        return null == str || "".equals(str.trim());
    }

    /**
     * 判断一个字符串是否不为空
     *
     * @param str 需要判断的字符串
     * @return 是否为空
     */
    public static boolean isNotBlank(String str) {
        return !isBlank(str);
    }

    /**
     * 判断一组字符串是否有空值
     *
     * @param strs 需要判断的一组字符串
     * @return 判断结果，只要其中一个字符串为null或者为空，就返回true
     */
    public static boolean hasBlank(String... strs) {
        if (null == strs || 0 == strs.length) {
            return true;
        } else {
            //这种代码如果用java8就会很优雅了
            for (String str : strs) {
                if (isBlank(str)) {
                    return true;
                }
            }
        }
        return false;
    }


    public static String mapToXmlStr(Map map) {

        StringBuilder sb = new StringBuilder("<xml>");
        for (Object obj : map.keySet()) {
            sb.append("<" + String.valueOf(obj) + ">").append(map.get(obj)).append("</" + String.valueOf(obj) + ">");
        }
        sb.append("</xml>");
        return sb.toString();
    }

    public static String mapToXmlStrWithOrder(Map map) {
        List<String> keys = Lists.newArrayList(map.keySet());
        Collections.sort(keys);
        StringBuilder sb = new StringBuilder("<xml>");
        for (String key : keys) {
            if (!key.equals("sign")) {
                sb.append("<" + String.valueOf(key) + ">").append(map.get(key)).append("</" + String.valueOf(key) + ">");
            }
        }
        sb.append("<" + String.valueOf("sign") + ">").append(map.get("sign")).append("</" + String.valueOf("sign") + ">");
        sb.append("</xml>");
        return sb.toString();
    }

    /**
     * xml to json <node><key label="key1">value1</key></node> 转化为
     * {"key":{"@label":"key1","#text":"value1"}}
     *
     * @param
     * @return
     */
/*    public static String xmltoJson(String xml) {
        XMLSerializer xmlSerializer = new XMLSerializer();
        return xmlSerializer.read(xml).toString();
    }*/
    public static boolean listHasText(String... strs) {
        if (null == strs || 0 == strs.length) {
            return false;
        } else {
            //这种代码如果用java8就会很优雅了
            for (String str : strs) {
                if (hasText(str)) {
                    return true;
                }
            }
        }
        return false;

    }

    public static boolean hasText(String str) {
        if (!hasLength(str)) {
            return false;
        }
        int strLen = str.length();
        for (int i = 0; i < strLen; i++) {
            if (!Character.isWhitespace(str.charAt(i))) {
                return true;
            }
        }
        return false;
    }

    public static boolean hasLength(String str) {
        return (str != null && str.length() > 0);
    }

    public static List<Integer> strSplitToArray(String value) {
        if (Strings.isNullOrEmpty(value)) {
            return null;
        }
        String[] idStrList = value.trim().split(",");
        List<Integer> idInList = Lists.newArrayList();
        for (String idStr : idStrList) {
            idInList.add(Integer.valueOf(idStr));
        }
        return idInList;
    }

    /*过滤html标题，返回纯文本*/
    public static String delHTMLTag(String htmlStr) {
        String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; //定义script的正则表达式
        String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>"; //定义style的正则表达式
        String regEx_html = "<([^>]*)>"; //定义HTML标签的正则表达式

        Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
        Matcher m_script = p_script.matcher(htmlStr);
        htmlStr = m_script.replaceAll(""); //过滤script标签

        Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
        Matcher m_style = p_style.matcher(htmlStr);
        htmlStr = m_style.replaceAll(""); //过滤style标签

        Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
        Matcher m_html = p_html.matcher(htmlStr);
        htmlStr = m_html.replaceAll(""); //过滤html标签
        StringBuffer filtered = new StringBuffer(htmlStr.length());
        char c;
        for (int i = 0; i <= htmlStr.length() - 1; i++) {
            c = htmlStr.charAt(i);
            switch (c) {
                case '<':
                    filtered.append("&lt;");
                    break;
                case '>':
                    filtered.append("&gt;");
                    break;
                case '"':
                    filtered.append("&quot;");
                    break;
                case '&':
                    filtered.append("&amp;");
                    break;
                default:
                    filtered.append(c);
            }
        }
        return htmlStr.trim(); //返回文本字符串
    }

    /**
     * 格式化文本, {} 表示占位符<br>
     * 例如：format("aaa {} ccc", "bbb")   ---->    aaa bbb ccc
     *
     * @param template 文本模板，被替换的部分用 {} 表示
     * @param values   参数值
     * @return 格式化后的文本
     */
    public static String format(String template, Object... values) {
        if (BeanUtil.isEmptyArray(values) || isBlank(template)) {
            return template;
        }

        final StringBuilder sb = new StringBuilder();
        final int length = template.length();

        int valueIndex = 0;
        char currentChar;
        for (int i = 0; i < length; i++) {
            if (valueIndex >= values.length) {
                sb.append(sub(template, i, length));
                break;
            }

            currentChar = template.charAt(i);
            if (currentChar == '{') {
                final char nextChar = template.charAt(++i);
                if (nextChar == '}') {
                    sb.append(values[valueIndex++]);
                } else {
                    sb.append('{').append(nextChar);
                }
            } else {
                sb.append(currentChar);
            }

        }

        return sb.toString();
    }

    /**
     * 改进JDK subString<br>
     * index从0开始计算，最后一个字符为-1<br>
     * 如果from和to位置一样，返回 "" example: abcdefgh 2 3 -> c abcdefgh 2 -3 -> cde
     *
     * @param string    String
     * @param fromIndex 开始的index（包括）
     * @param toIndex   结束的index（不包括）
     * @return 字串
     */
    public static String sub(String string, int fromIndex, int toIndex) {
        int len = string.length();

        if (fromIndex < 0) {
            fromIndex = len + fromIndex;

            if (toIndex == 0) {
                toIndex = len;
            }
        }

        if (toIndex < 0) {
            toIndex = len + toIndex;
        }

        if (toIndex < fromIndex) {
            int tmp = fromIndex;
            fromIndex = toIndex;
            toIndex = tmp;
        }

        if (fromIndex == toIndex) {
            return EMPTY;
        }

        char[] strArray = string.toCharArray();
        char[] newStrArray = Arrays.copyOfRange(strArray, fromIndex, toIndex);
        return new String(newStrArray);
    }

    public static boolean emailIsIllegal(String email) {
        Pattern p = Pattern.compile("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?");
        if (null != email) {
            email = email.trim();
        } else {
            return true;
        }
        Matcher m = p.matcher(email);
        return !m.matches();
    }

    // ^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,18}$
    public static boolean passwordIsIllegal(String pwd) {
        Pattern p = Pattern.compile("^[0-9A-Za-z]{6,18}$");
        if (null != pwd) {
            pwd = pwd.trim();
        } else {
            return true;
        }
        Matcher m = p.matcher(pwd);
        return !m.matches();
    }

    /**
     * @return
     * @Author SGY
     * @Date 2019/7/3 17:52
     * @Param
     * @Description // 验证是否是逗号和数字组合的字符串
     **/
    public static boolean splitCommaIsIllegal(String str) {
        Pattern p = Pattern.compile("^(\\d+,?)+$");
        if (null != str) {
            str = str.trim();
        } else {
            return true;
        }
        Matcher m = p.matcher(str);

        boolean flag = m.matches();

        return !flag;
    }



    /**
     * @return
     * @Author SGY
     * @Date 2019/7/19 14:29
     * @Param
     * @Description // 用户名必须是2-11位之间的汉字、字母、数字、下划线
     **/
    public static boolean usernameIllegal(String username) {
        Pattern p = Pattern.compile("^[a-zA-Z0-9_\\u4e00-\\u9fa5]{2,11}$");
        if (null != username) {
            username = username.trim();
        } else {
            return true;
        }
        Matcher m = p.matcher(username);

        boolean flag = m.matches();

        return !flag;
    }

    public static boolean chineseIllegal(String username) {
        Pattern p = Pattern.compile("^[\\u4e00-\\u9fa5]{2,30}$");
        if (null != username) {
            username = username.trim();
        } else {
            return true;
        }
        Matcher m = p.matcher(username);

        boolean flag = m.matches();

        return !flag;
    }

    public static void main(String[] args) {

    }


    /**
     * 获取随机字符
     *
     * @return
     */
    public static String getRandomString() {
        String string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        String random1 = RandomStringUtils.random(8, string);
        return random1;
    }



    /**
     * @return
     * @Author SGY
     * @Date 2020/2/18 17:03
     * @Param
     * @Description // 空或null或超出长度返回true
     **/
    public static boolean isBlankOrTooLong(String str, int length) {
        if (isBlank(str)) {
            return true;
        } else {
            if (str.length() > length) {
                return true;
            } else {
                return false;
            }
        }
    }


    /**
     * @param
     * @return
     * @Author SGY
     * @Date 2020/4/30 10:47
     * @Description // 获取n位随机数
     **/
    public static String getRandom(int n) {
        /*订单号生成，保证唯一就行*/
        StringBuilder sRand = new StringBuilder(n);
        for (int i = 0; i < n; i++) {
            // 取得一个随机数字
            String tmp = random.nextInt(9) + "";
            sRand.append(tmp);
        }
        return sRand.toString();
    }


    /**
     * @param hours 0-23
     * @return
     * @Author SGY
     * @Date 2020/6/24 16:16
     * @Description // 获取时间段
     **/
    public static String getTimeSlot(Integer hours) {
        switch (hours) {
            case 0:
                return "00:00-01:00";
            case 1:
                return "01:00-02:00";
            case 2:
                return "02:00-03:00";
            case 3:
                return "03:00-04:00";
            case 4:
                return "04:00-05:00";
            case 5:
                return "05:00-06:00";
            case 6:
                return "06:00-07:00";
            case 7:
                return "07:00-08:00";
            case 8:
                return "08:00-09:00";
            case 9:
                return "09:00-10:00";
            case 10:
                return "10:00-11:00";
            case 11:
                return "11:00-12:00";
            case 12:
                return "12:00-13:00";
            case 13:
                return "13:00-14:00";
            case 14:
                return "14:00-15:00";
            case 15:
                return "15:00-16:00";
            case 16:
                return "16:00-17:00";
            case 17:
                return "17:00-18:00";
            case 18:
                return "18:00-19:00";
            case 19:
                return "19:00-20:00";
            case 20:
                return "20:00-21:00";
            case 21:
                return "21:00-22:00";
            case 22:
                return "22:00-23:00";
            case 23:
                return "23:00-00:00";
            default:
                return "";
        }

    }

    /**
     * @param
     * @return
     * @Author SGY
     * @Date 2020/7/9 16:13
     * @Description // 获取当天零点的时间戳
     **/
    public static long getTodayStartTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime().getTime();
    }

    /**
     * @param
     * @return
     * @Author SGY
     * @Date 2020/7/10 10:20
     * @Description // 获取零点的时间戳
     **/
    public static long getDateStartTime(Date useDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(useDate);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime().getTime();
    }

    public static boolean checkDate(Date useDate, Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(useDate);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        Calendar instance = Calendar.getInstance();
        instance.setTime(date);
        instance.set(Calendar.HOUR_OF_DAY, 0);
        instance.set(Calendar.MINUTE, 0);
        instance.set(Calendar.SECOND, 0);
        instance.set(Calendar.MILLISECOND, 0);
        return calendar.getTime().getTime() == instance.getTime().getTime();
    }

    /**
     * 生成业务流水号
     *
     * @return
     */
    public static String generateSerialNo() {
        StringBuilder sRand = new StringBuilder(40);
        sRand.append("R");
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String str = sdf.format(date);
        sRand.append(str);
        for (int i = 0; i < 10; i++) {
            // 取得一个随机字符
            String tmp = StringUtil.getRandomChar() + "";
            sRand.append(tmp);
        }
        return sRand.toString();
    }

    /**
     * 手动分页限制页数
     *
     * @param list
     * @param pageNum
     * @param <T>
     * @return
     */
    public static <T> List<List<T>> splitNumList(List<T> list, int pageNum) {
        int listSize = list.size();
        int pageSize = (int) Math.ceil((double) listSize / pageNum); // 向上取整, 获得每页大小
        List<List<T>> listArray = new ArrayList<List<T>>();

        for (int i = 0; i < pageNum; i++) {
            List<T> subList = new ArrayList<T>();
            for (int j = 0; j < listSize; j++) {
                int num = i * pageSize + j; // 当前下标
                if (num >= listSize) {
                    break;
                }
                if (j == pageSize) {
                    break;
                }
                subList.add(list.get(num));
            }
            listArray.add(subList);
        }
        return listArray;
    }

    /**
     * 手动分页限制条数
     *
     * @param list
     * @param pageSize
     * @param list     切割集合
     * @param pageSize 每页大小
     * @return List<List < T>>返回分页数据
     */
    public static <T> List<List<T>> splitSizeList(List<T> list, int pageSize) {
        int listSize = list.size();
        int page = (listSize + (pageSize - 1)) / pageSize;
        List<List<T>> listArray = new ArrayList<List<T>>();
        for (int i = 0; i < page; i++) {
            List<T> subList = new ArrayList<T>();
            for (int j = 0; j < listSize; j++) {
                int pageIndex = ((j + 1) + (pageSize - 1)) / pageSize;
                if (pageIndex == (i + 1)) {
                    subList.add(list.get(j));
                }
                if ((j + 1) == ((j + 1) * pageSize)) {
                    break;
                }
            }
            listArray.add(subList);
        }
        return listArray;
    }

    /**
     * 获取当前周数
     *
     * @return
     */
    public static int getWeeks() {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setTime(new Date());
        int weeks = calendar.get(Calendar.WEEK_OF_YEAR);
        return weeks;
    }

    public static int getWeeksByDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setTime(date);
        int weeks = calendar.get(Calendar.WEEK_OF_YEAR);
        return weeks;
    }

    /**
     * 获取当前星期几
     *
     * @return
     */
    public static int getWeekTo() {
        int[] arr = {7, 1, 2, 3, 4, 5, 6}; // 对应星期几
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        int weekTo = calendar.get(Calendar.DAY_OF_WEEK);
        return arr[weekTo - 1];
    }

    /**
     * 获取对应日期的星期
     * @return
     */
    public static int getWeekToByDate(Date date) {
        int[] arr = {7, 1, 2, 3, 4, 5, 6}; // 对应星期几
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int weekTo = calendar.get(Calendar.DAY_OF_WEEK);
        return arr[weekTo - 1];
    }

    /**
     * 获取该日期的周一的日期
     * @param date 传入当前日期
     * @return
     */
    public static Date getThisWeekMonday(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int day = cal.get(Calendar.DAY_OF_WEEK);
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
        return cal.getTime();
    }

    /**
     * 获取真实ip
     *
     * @param request
     * @return
     */
    public static String getIPAddress(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (!isBlank(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            //多次反向代理后会有多个ip值，第一个ip才是真实ip
            int index = ip.indexOf(",");
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        }
        ip = request.getHeader("X-Real-IP");
        if (!isBlank(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            return ip;
        }
        return request.getRemoteAddr();
    }

    /**
     * 校验字符串是否是数值类型
     *
     * @param str
     * @return
     */
    public static boolean numberCharIsIllegal(String str) {
        Pattern p = Pattern.compile("^(-?\\d+)(\\.\\d+)?$");
        if (null != str) {
            str = str.trim();
        } else {
            return true;
        }
        Matcher m = p.matcher(str);

        boolean flag = m.matches();

        return !flag;
    }

    /**
     * 校验字符串是否是正实数
     * @param str
     * @return
     */
    public static boolean positiveNumberStrIsIllegal(String str) {
        Pattern p = Pattern.compile("^[0-9]+(.[0-9]{1,10})?$");
        if (null != str) {
            str = str.trim();
        } else {
            return true;
        }
        Matcher m = p.matcher(str);

        boolean flag = m.matches();

        return !flag;
    }

    public static boolean deviceNameIsIllegal1(String str) {
        Pattern p = Pattern.compile("^[\\w\\d@_\\-\\.\\:]{4,32}");
        if (null != str) {
            str = str.trim();
        } else {
            return true;
        }
        Matcher m = p.matcher(str);

        boolean flag = m.matches();

        return !flag;
    }

    // 8个16进制字符串
    public static boolean deviceNameIsIllegal(String str) {
        Pattern p = Pattern.compile("^[A-Fa-f0-9]{8}$");
        if (null != str) {
            str = str.trim();
        } else {
            return true;
        }
        Matcher m = p.matcher(str);

        boolean flag = m.matches();

        return !flag;
    }

    /**
     * YYYY-MM-DDThh:mm:ssZ
     * 2016-01-04T12:00:00Z表示北京时间2016年01月04日20点0分0秒
     * @return
     */
    public static String getTimestampUTC() throws ParseException {
        Calendar calendar = Calendar.getInstance();
        int offset = calendar.get(Calendar.ZONE_OFFSET);
        calendar.add(Calendar.MILLISECOND, -offset);
        Date date = calendar.getTime();
        String format = dateFormat.format(date);
        String replace = format.replace(" ", "T");
        replace += "Z";
        return replace;
    }

    /**
     * 一位实数，保留一位小数
     * @return
     */
    public static boolean pointOneIsIllegal(String str) {
        Pattern p = Pattern.compile("^(-?[0-9]+)(.[0-9]{1})?$");
        if (null != str) {
            str = str.trim();
        } else {
            return true;
        }
        Matcher m = p.matcher(str);

        boolean flag = m.matches();

        return !flag;
    }

    /**
     * 百分比
     * @param a
     * @param b
     * @return
     */
    public static BigDecimal percentage(BigDecimal a, BigDecimal b) {
        if (a.compareTo(BigDecimal.ZERO) == 0 || b.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        } else {
            BigDecimal divide = a.divide(b, 4, BigDecimal.ROUND_DOWN);
            return divide.multiply(BigDecimal.valueOf(100));
        }
    }

    /**
     * 补位成两位数
     * @param i
     * @return
     */
    public static String complement2digit(int i) {
        if (i > 9) {
            return i + "";
        } else {
            return "0" + i;
        }
    }


    /**
     * 判断两个字符串是否一致
     *
     * @param a
     * @param b
     * @return
     */
    public static boolean equalsStr(String a, String b) {
        if (StringUtil.isBlank(a)) {
            if (StringUtil.isBlank(b)) {
                return true;
            } else {
                return false;
            }
        } else {
            if (StringUtil.isBlank(b)) {
                return true;
            } else {
                return a.equals(b);
            }
        }
    }

    /**
     * 判断两个BigDecimal是否一致
     *
     * @param a
     * @param b
     * @return
     */
    public static boolean equalsBigDecimal(BigDecimal a, BigDecimal b) {
        if (a == null) {
            if (b == null) {
                return true;
            } else {
                return false;
            }
        } else {
            if (b == null) {
                return false;
            } else {
                return a.compareTo(b) == 0;
            }
        }
    }

    /**
     * 判断两个Short是否一致
     *
     * @param a
     * @param b
     * @return
     */
    public static boolean equalsShort(Short a, Short b) {
        if (a == null) {
            if (b == null) {
                return true;
            } else {
                return false;
            }
        } else {
            if (b == null) {
                return true;
            } else {
                return a.compareTo(b) == 0;
            }
        }
    }

    /**
     * 判断两个Date是否一致
     *
     * @param a
     * @param b
     * @return
     */
    public static boolean equalsDate(Date a, Date b) {
        if (a == null) {
            if (b == null) {
                return true;
            } else {
                return false;
            }
        } else {
            if (b == null) {
                return true;
            } else {
                return a.compareTo(b) == 0;
            }
        }
    }

    //异或
    public static String eh(String code1, String code2){
        String result ="";
        for(int i=0; i<code1.length();i++){
            char c1 = code1.charAt(i);
            char c2 = code2.charAt(i);
            String a = convertHexToBinary(c1+"");
            String b = convertHexToBinary(c2+"");
            byte [] aa = a.getBytes();
            byte [] bb = b.getBytes();
            String cc ="";
            for( int j = 0;j<aa.length;j++ ){
                cc += aa[j]^bb[j];
            }
            String tmp =Integer.toHexString(Integer.valueOf(cc,2).intValue()).toString();
            result +=tmp;
        }
        return result;
    }

    public static String convertHexToBinary(String hexString){
        long l = Long.parseLong(hexString, 16);
        String binaryString = Long.toBinaryString(l);
        int shouldBinaryLen = hexString.length()*4;
        StringBuffer addZero = new StringBuffer();
        int addZeroNum = shouldBinaryLen-binaryString.length();
        for(int i=1;i<=addZeroNum;i++){
            addZero.append("0");
        }
        return addZero.toString()+binaryString;
    }

    private static char[] hexChar = "0123456789abcdef".toCharArray();

    public static String getRandom(){
        Random random = new Random();
        StringBuilder sRand = new StringBuilder(8);
        for (int i = 0; i < 16; i++) {
            // 取得一个随机字符
            int index = random.nextInt(hexChar.length);
            sRand.append(String.valueOf(hexChar[index]));
        }
        return sRand.toString();
    }

    private static char[] hexBigChar = "0123456789ABCDEF".toCharArray();

    public static String getAppId(){
        Random random = new Random();
        StringBuilder sRand = new StringBuilder(16);
        for (int i = 0; i < 16; i++) {
            // 取得一个随机字符
            int index = random.nextInt(hexBigChar.length);
            sRand.append(String.valueOf(hexBigChar[index]));
        }
        return sRand.toString();
    }

    public static String getAppKey(){
        Random random = new Random();
        StringBuilder sRand = new StringBuilder(32);
        for (int i = 0; i < 32; i++) {
            // 取得一个随机字符
            int index = random.nextInt(hexBigChar.length);
            sRand.append(String.valueOf(hexBigChar[index]));
        }
        return sRand.toString();
    }


    public static String doAddZero(String code, Integer size){
        String returnCode = code;
        if (code.length() < size){
            String addCode = "";
            for (int i=0;i<size-code.length();i++){
                addCode = addCode + "0";
            }
            returnCode = addCode + returnCode;
        }
        return returnCode;
    }


    //判断奇偶数,true为奇数
    public static boolean isOdd(int a){
        if(a%2 == 1){   //是奇数
            return true;
        }
        return false;
    }

    public static String toPinYin(String chineseLan) {
        String ret = "";
        // 将汉字转换为字符数组
        char[] charChineseLan = chineseLan.substring(0, 1).toCharArray();
        // 定义输出格式
        HanyuPinyinOutputFormat hpFormat = new HanyuPinyinOutputFormat();
        // 小写格式输出
        hpFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        // 不需要语调输出
        hpFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        try {
            for (int i = 0; i < charChineseLan.length; i++) {
                if (String.valueOf(charChineseLan[i]).matches("[\u4e00-\u9fa5]+")) {
                    // 如果字符是中文,则将中文转为汉语拼音（获取全拼则去掉红色的代码即可）
                    ret += PinyinHelper.toHanyuPinyinStringArray(charChineseLan[i], hpFormat)[0].substring(0, 1);
                } else {
                    // 如果字符不是中文,则不转换
                    ret += charChineseLan[i];
                }
            }
        } catch (BadHanyuPinyinOutputFormatCombination e) {
            BaseLogger.printErrorInfo(e);
        }
        return ret.toUpperCase();
    }

    public static String removeDuplicates(String[] input) {
        Set<String> set = new HashSet<>();
        for (String c : input) {
            set.add(c);
        }
        return String.join(",", set);
    }

    public static boolean containsString(String[] array, String target) {
        for (String str : array) {
            if (str.equals(target)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 从原始数组中移除指定的元素
     * @param original 原始数组
     * @param toRemove 需要移除的元素数组
     * @return 过滤后的新数组
     */
    public static String[] removeElementsByString(String[] original, String[] toRemove) {
        // 将需要移除的元素转换为集合，便于查找
        List<String> removeList = Arrays.asList(toRemove);
        // 创建一个列表来存储保留的元素
        List<String> resultList = new ArrayList<>();
        // 遍历原始数组，将不在移除列表中的元素添加到结果列表
        for (String element : original) {
            if (!removeList.contains(element)) {
                resultList.add(element);
            }
        }
        // 将列表转换为数组并返回
        return resultList.toArray(new String[0]);
    }

    /**
     * 从原始数组中移除指定的元素
     * @param original 原始数组
     * @param removeList 需要移除的元素数组
     * @return 过滤后的新数组
     */
    public static String[] removeElementsByList(String[] original, List<String> removeList) {
        // 创建一个列表来存储保留的元素
        List<String> resultList = new ArrayList<>();
        // 遍历原始数组，将不在移除列表中的元素添加到结果列表
        for (String element : original) {
            if (!removeList.contains(element)) {
                resultList.add(element);
            }
        }
        // 将列表转换为数组并返回
        return resultList.toArray(new String[0]);
    }

}
